/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

package pdf;

import com.lowagie.text.Document;
import com.lowagie.text.DocumentException;
import com.openbrew.openbrewrf.Administration;
import java.awt.Color;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.OutputStream;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import javax.imageio.ImageIO;
import view.SimpleSalesOrderView;
import com.lowagie.text.PageSize;
import com.lowagie.text.pdf.PdfContentByte;
import com.lowagie.text.pdf.PdfWriter;
import com.openbrew.openbrewrf.Customer;
import com.openbrew.openbrewrf.Employee;
import com.openbrew.openbrewrf.SalesOrder;
import java.io.ByteArrayInputStream;
import java.io.InputStream;

/**
 *
 * @author chapmand
 */
public class SOPDFCreator {
    private SimpleSalesOrderView simpleSalesOrderView = null;
    private Administration admin = null;
    private String leftOver = null;
    private int linespace = 10;
        
    private final int borderSize = 50;
    private static final String HELVETICA = "helvetica";
    private static final Font TITLE_FONT = new Font(HELVETICA, Font.BOLD, 12);
    private static final Font TEXT_FONT = new Font(HELVETICA, Font.PLAIN, 8);
    private final DateFormat dateFormat = new SimpleDateFormat("MM/dd/yyyy");
    
    private void setView(final SimpleSalesOrderView simpleSalesOrderView, final Administration admin){
        this.simpleSalesOrderView = simpleSalesOrderView;
        this.admin = admin;
    }
    
    private void addGraphics(final Graphics2D g2d){
        // Print Logos (Logo.JPG and BLogo.JPG
        BufferedImage image = null;
        BufferedImage image2 = null;
        if(admin.getHeaderImg()!=null){
            try{
                InputStream in = new ByteArrayInputStream(admin.getHeaderImg());
                BufferedImage hdrbi = ImageIO.read(in);  
                image = hdrbi;
            } catch (IOException ex){

            }
        }
        if(admin.getFooterImg()!=null){
            try{
                InputStream in = new ByteArrayInputStream(admin.getFooterImg());
                BufferedImage hdrbi = ImageIO.read(in);  
                image2 = hdrbi;
            } catch (IOException ex){

            }
        }
        // Render the image on the sheet
        g2d.drawImage(image, borderSize, borderSize, 66, 100, null);
        final double imgy = (PageSize.A4.getHeight() - 66 - borderSize);
        final double imgx = (PageSize.A4.getWidth() - 66 - borderSize);
        // Render second image on sheet.
        g2d.drawImage(image2, (int) imgx, (int) imgy, 66, 66, null);
    }
    
    private void addCustomerInvoiceData(final Graphics2D g2d, final SalesOrder salesOrder, final String sales){
        FontMetrics fontMetrics = g2d.getFontMetrics();
        Customer customer = salesOrder.getSOCust();
        // -- Section 2 (Customer data and invoice)
        // Print Customer Data:
        final String custTo = "TO:";
        final String custName = customer.getCName();
        final String custAddr = customer.getCAddr();
        final String custCSZ = customer.getCCity() + ", " + customer.getCState() + " " + customer.getCZip();
        final String custPhone = customer.getCPhone();

        // Calculate Customer Position.
        final int cY = 180 + borderSize;
        double textX = (fontMetrics.stringWidth(custTo) + 6) + borderSize;
        g2d.drawString(custTo, borderSize, (cY + (linespace * 1)));
        g2d.drawString(custName, (int) textX, (cY + (linespace * 1)));
        g2d.drawString(custAddr, (int) textX, (cY + (linespace * 2)));
        g2d.drawString(custCSZ, (int) textX, (cY + (linespace * 3)));
        g2d.drawString(custPhone, (int) textX, (cY + (linespace * 4)));

        // -- Section 2 Part B List Invoice.

        final int dateFieldXPosition = 0 + borderSize;
	final int itemCostFieldXPosition = 300 + borderSize;
        final int productFieldXPosition = 350 + borderSize;
        final int costFieldXPosition = 400 + borderSize;
        int tY = cY + (linespace * 6);

        // Print out headers of file.
        String headerDate = "Product:";
	final String itemCostProduct = "Price:";
        final String headerProduct = "Qty:";
        final String headerCost = "Cost:";

        g2d.drawString(headerDate, dateFieldXPosition, tY);
	g2d.drawString(itemCostProduct, itemCostFieldXPosition, tY);
        g2d.drawString(headerProduct, productFieldXPosition, tY);
        g2d.drawString(headerCost, (int) costFieldXPosition, tY);

        tY += linespace;

        String[] salesArray = sales.split("\n");
        leftOver = null;
        int count = 0;
        for (final String element : salesArray) {
                count++;
                if(count >=40){
                    if(leftOver == null){
                        leftOver = element + "\n";
                    } else {
                        leftOver += element + "\n";
                    }
                } else {
                    headerDate = dateFormat.format(salesOrder.getSODate());
                    final String[] totals = element.split(",");

                    g2d.drawString(totals[0], dateFieldXPosition, tY);
                    g2d.drawString(totals[1], itemCostFieldXPosition, tY);
                    g2d.drawString(totals[2], productFieldXPosition, tY);
                    g2d.drawString(totals[3], (int) costFieldXPosition, tY);

                    tY += linespace;
                }
        }

        tY += linespace;
        
        if(leftOver == null){
            final String totalCost = simpleSalesOrderView.getCost();
            final String ttl = "Total:";

            final double ttlX = costFieldXPosition - fontMetrics.stringWidth(ttl) - 5;

            g2d.drawString(totalCost, (int) costFieldXPosition, tY);
            g2d.drawString(ttl, (int) ttlX, tY);

            tY += linespace;
            final String totalKegs = "Total Kegs Checked Out To Customer: " 
                + Integer.toString(simpleSalesOrderView.getNumKegs());
            g2d.drawString(totalKegs, dateFieldXPosition, tY);
        }
    }
    
    private void addHeaderInfo(final Graphics2D g2d, final SalesOrder salesOrder){
        // ---Section 1 (Header)
            // Print the header
            final String titleText = admin.getBreweryName();
            g2d.setFont(TITLE_FONT);

            // Comput the right alignment on the page.
            FontMetrics fontMetrics = g2d.getFontMetrics();
            final double titleX = (PageSize.A4.getWidth()- borderSize) - (fontMetrics.stringWidth(titleText));
            final double titleY = 14 + borderSize;
            g2d.drawString(titleText, (int) titleX, (int) titleY);

            // Print the address.
            final String addressText0 = admin.getBreweryStreetAddress() + " "
                    + admin.getBreweryCity() + ", " + admin.getBreweryState() + " "
                    + admin.getBreweryZipCode();
            final String addressText1 = admin.getBreweryPhoneNumber();
            final String addressText2 = admin.getBreweryEmail();
            final int addressY = 14 + borderSize;
            g2d.setFont(TEXT_FONT);

            // Compute the right alignment for the address info.
            fontMetrics = g2d.getFontMetrics();
            double addressX = (PageSize.A4.getWidth()- borderSize) - (fontMetrics.stringWidth(addressText0));
            g2d.drawString(addressText0, (int) addressX, (addressY + (linespace * 1)));
            addressX = (PageSize.A4.getWidth()- borderSize) - (fontMetrics.stringWidth(addressText1));
            g2d.drawString(addressText1, (int) addressX, (addressY + (linespace * 2)));
            addressX = (PageSize.A4.getWidth()- borderSize) - (fontMetrics.stringWidth(addressText2));
            g2d.drawString(addressText2, (int) addressX, (addressY + (linespace * 3)));

            // Get Sales Order information.
            Customer customer = null;
            customer = salesOrder.getSOCust();

            final String invoiceNumber = salesOrder.getDisplayID();

            // Print Invoice Data:
            final String invoiceNumberString = "INVOICE NUMBER: " + invoiceNumber;
            final String invoiceDateString = "INVOICE DATE: " + dateFormat.format(salesOrder.getSODate());
            final String invoiceDueString = "DUE DATE: " + dateFormat.format(salesOrder.getDueDate(customer.getCTerms()));
            g2d.setFont(TEXT_FONT);

            // Compute the right alignment for the invoice info.
            fontMetrics = g2d.getFontMetrics();
            double textX = (PageSize.A4.getWidth()- borderSize) - (fontMetrics.stringWidth(invoiceNumberString));
            final int iY = (addressY + (linespace * 5));
            g2d.drawString(invoiceNumberString, (int) textX, (iY + (linespace * 1)));
            textX = (PageSize.A4.getWidth()- borderSize) - (fontMetrics.stringWidth(invoiceDateString));
            g2d.drawString(invoiceDateString, (int) textX, (iY + (linespace * 2)));
            textX = (PageSize.A4.getWidth()- borderSize) - (fontMetrics.stringWidth(invoiceDueString));
            g2d.drawString(invoiceDueString, (int) textX, (iY + (linespace * 3)));
    }
    
    private void addFooterData(final Graphics2D g2d){
        // -- Section 3 (Footer)
        Employee billingEmp = admin.getBillingEmp();
        Employee salesEmp = admin.getSalesEmp();
        // Print Contact Info.
        final String gContact = "Contact Info:";
        final String gBilling = "Billing: " + billingEmp.getEmpFirstName() + " " 
                + billingEmp.getEmpLastName() + " - " + billingEmp.getEmpPhone();
        final String gBillingAddr = billingEmp.getEmpEmail();
        final String gSales = "Sales: " + salesEmp.getEmpFirstName() + " " 
                + salesEmp.getEmpLastName() + " - " + salesEmp.getEmpPhone();
        final String gSalesAddr = salesEmp.getEmpEmail();

        // Compute and display contact info.
        double textX = 0 + borderSize;
        final double textY = (PageSize.A4.getHeight() - 66 - borderSize);
        linespace = 10;

        g2d.drawString(gContact, (int) textX, (int) textY);
        g2d.drawString(gBilling, (int) textX, ((int) textY + (linespace * 2)));
        g2d.drawString(gBillingAddr, (int) textX, ((int) textY + (linespace * 3)));
        g2d.drawString(gSales, (int) textX, ((int) textY + (linespace * 5)));
        g2d.drawString(gSalesAddr, (int) textX, ((int) textY + (linespace * 6)));
    }
    
    private void makeSOView(final Graphics2D g2d, SalesOrder salesOrder, SimpleSalesOrderView simpleSalesOrderView, Administration admin){
        setView(simpleSalesOrderView, admin);
        g2d.setPaint(Color.BLACK);
        //Draw Graphics to PDF.
        addGraphics(g2d);

        //Draw Header to PDF.
        addHeaderInfo(g2d, salesOrder);

        //Draw Invoice Data to PDF.
        addCustomerInvoiceData(g2d, salesOrder, simpleSalesOrderView.getOverview());

        //Draw Footer Data to PDF.
        addFooterData(g2d);
    }
    
    private void makeSONView(final Graphics2D g2d2, SalesOrder salesOrder, final String sales){
        g2d2.setPaint(Color.BLACK);
        
        //Draw Graphics to PDF.
        addGraphics(g2d2);

        //Draw Header to PDF.
        addHeaderInfo(g2d2, salesOrder);

        //Draw Invoice Data to PDF.
        addCustomerInvoiceData(g2d2, salesOrder, sales);

        //Draw Footer Data to PDF.
        addFooterData(g2d2);
    }
    
    public void createPDF(OutputStream outputStream, SalesOrder salesOrder, SimpleSalesOrderView simpleSalesOrderView, final Administration admin){
        try{
            Document document = new Document(PageSize.A4, borderSize, borderSize, borderSize, borderSize);
            //PdfWriter.getInstance(document, outputStream);   
            PdfWriter writer = PdfWriter.getInstance(document, outputStream);
            document.open();
            PdfContentByte canvas = writer.getDirectContent();
            // Create the Graphics2D object.
            Graphics2D g2d = canvas.createGraphics(PageSize.A4.getWidth(), PageSize.A4.getHeight());
            
            //Create page 1 image
            makeSOView(g2d, salesOrder, simpleSalesOrderView, admin);
            
            g2d.dispose();
            
            if(leftOver != null){
                appendPDFPage(document, canvas, leftOver, salesOrder);
            }
            
            document.close();
        }catch(DocumentException ex){
            
        }
    }
    
    private void appendPDFPage(final Document document, final PdfContentByte canvas, final String sales, final SalesOrder salesOrder){
        document.newPage();
        Graphics2D g2d2 = canvas.createGraphics(PageSize.A4.getWidth(), PageSize.A4.getHeight());
        
        //Create Next Page View.
        makeSONView(g2d2, salesOrder, sales);

        g2d2.dispose();
        if(leftOver != null){
            appendPDFPage(document, canvas, leftOver, salesOrder);
        }
    }
    
}
